package com.szmmsoft.mp.common.until;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.szmmsoft.mp.common.constant.Constants;
import com.szmmsoft.mp.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.util.ContentCachingRequestWrapper;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * Description of the class.
 *
 * @author ethan
 * @version 1.0.0
 * @since 2024-10-14
 */
@Slf4j
public class SignUtil {
    private static final String SGINKEY = "aDpz@WbX#$%K";

    /**
     * 获取签名
     *
     * @param map
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String sign(Map<String, String> map) throws UnsupportedEncodingException {
        String sortedStr = getSortedParamStr(map);
        String paraStr = SGINKEY + sortedStr;
        return SecureUtil.sha1(paraStr);
    }

    /**
     * 签名校验
     *
     * @param request
     * @throws UnsupportedEncodingException
     */
    public static void checkSign(HttpServletRequest request) throws UnsupportedEncodingException {
        if (!"POST".equals(request.getMethod())){
            throw new BusinessException("只支持POST请求，不支持其他请求");
        }
        String bodyParam = null;
        if (request instanceof ContentCachingRequestWrapper) {
            bodyParam = new String(((ContentCachingRequestWrapper) request).getContentAsByteArray(), StandardCharsets.UTF_8);
        }
        Map<String, String> map = JSONUtil.toBean(bodyParam, Map.class);

        String postSign = map.get(Constants.SIGN_KEY);
        if (CharSequenceUtil.isEmpty(postSign)) {
            throw new BusinessException("签名不可为空");
        }

        String timeStampStr = map.get(Constants.SIGN_TIME_KEY);
        if (CharSequenceUtil.isEmpty(timeStampStr)) {
            throw new BusinessException("签名不可为空");
        }

        Long timeStamp = Long.parseLong(timeStampStr);
        Long expireTime = timeStamp + Constants.SIGN_EXPIRE_TIME;
        if (System.currentTimeMillis() > expireTime) {
            throw new BusinessException("签名时间过期");
        }
        if (!Objects.equals(postSign, SignUtil.sign(map))) {
            throw new BusinessException("签名校验不通过");
        }
        log.info("校验签名通过");
    }

    /**
     * 构造自然排序请求参数
     *
     * @param params 请求
     * @return 字符串
     */
    private static String getSortedParamStr(Map<String, String> params) {
        Set<String> sortedParams = new TreeSet<>(params.keySet());

        StringBuilder strB = new StringBuilder();
        // 排除sign和空值参数
        for (String key : sortedParams) {
            if (Constants.SIGN_KEY.equalsIgnoreCase(key)) {
                continue;
            }

            String value = params.get(key);

            if (CharSequenceUtil.isNotEmpty(value)) {
                strB.append(key).append(value);
            }
        }
        return strB.toString();
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        Map<String,String>map = new HashMap<>();
        map.put("name","admin");
        map.put("pwd","123");
        String time = System.currentTimeMillis()+"";
        System.out.println(time);
        map.put(Constants.SIGN_TIME_KEY,time);
        System.out.println(sign(map));
    }
}
